home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 October: Mac OS SDK / Dev.CD Oct 97 SDK1.toast / Development Kits (Disc 1) / QuickDraw GX / Programming Stuff / Sample Code / Printing Samples / Printer Drivers… / ImageWriterLQ (alt. rdip) / ChooserSupport.c < prev    next >
Encoding:
Text File  |  1996-06-15  |  10.4 KB  |  355 lines  |  [TEXT/MPS ]

  1. /*---------------------------------------------------------------------------
  2. FILENAME
  3.     ChooserSupport.c
  4.  
  5. DESCRIPTION
  6.     This file contains the C code for the PACK and LDEF routines used by the
  7.     Chooser when the ImageWriter LQ driver is selected in the Chooser.
  8.         
  9. COPYRIGHT
  10.     Copyright Apple Computer, Inc. 1992-1996
  11.     All rights reserved. 
  12.     
  13. INTERFACE ROUTINES:
  14.     Device
  15.     LDEF
  16.     
  17.     12/20/93 - dmh - Sync'd with the shipping 1.0b3 GX driver.
  18.      8/28/94 - dmh - Sync'd with the shipping 1.0.1 GX driver.
  19.      8/28/94 - dmh - Universalized code.
  20.      6/14/96 - cn  - Updated to support Universal Interfaces 2.1.
  21.  
  22. -------------------------------------------------------------------------------- */
  23.  
  24. // Include the standard Mac header files 
  25. #include "MacIncludes.h"
  26.  
  27. // Include the new QuickDraw GX graphics header files 
  28. #include <GXGraphics.h>
  29.  
  30. // Include the required Printing Manager header files 
  31. #include <GXPrinterDrivers.h>
  32.  
  33. /*********************************************************************************
  34.  *                                         CONSTANTS                                                     *
  35.  *********************************************************************************/
  36.  
  37. // Chooser initialize message selector
  38. #define    initializeMsg            11
  39.  
  40. // Icon Suite support
  41.  
  42. #define    ttNone                    0x0000
  43. #define    ttDisabled                0x0001
  44. #define    ttOffline                0x0002
  45. #define    ttOpen                    0x0003
  46. #define    ttSelected                 0x4000
  47. #define    ttSelectedDisabled    (ttSelected + ttDisabled)
  48. #define    ttSelectedOffline        (ttSelected + ttOffline)
  49. #define    ttSelectedOpen            (ttSelected + ttOpen)
  50.  
  51. #define    ttLabel0                    0x0000
  52. #define    ttLabel1                    0x0100
  53. #define    ttLabel2                    0x0200
  54. #define    ttLabel3                    0x0300
  55. #define    ttLabel4                    0x0400
  56. #define    ttLabel5                    0x0500
  57. #define    ttLabel6                    0x0600
  58. #define    ttLabel7                    0x0700
  59.  
  60.  
  61. /*********************************************************************************
  62.  *                                    INLINE DECLARATIONS                                            *
  63. **********************************************************************************/
  64.  
  65. pascal OSErr PlotIconSuite(const Rect * theRect, short align, short iconTransform, Handle cIcon)
  66.     = {0x303C, 0x0603, 0xABC9};
  67.  
  68. pascal void OldDrawText(const void *textBuf,short firstByte,short byteCount)
  69.     = 0xA885; 
  70.  
  71.  
  72. /***************************************************************************************
  73. *                                         INTERFACE ROUTINES                                                     *
  74. ***************************************************************************************/                        
  75.  
  76.  
  77. /****************************************************************************************
  78.  
  79.                             Device
  80.                             
  81.     function:
  82.                 This routine is the interface routine for the Chooser PACK.  This is the
  83.                 routine the Chooser calls to perform the Chooser functions for the 
  84.                 ImageWriter LQ driver.
  85.                 
  86.     parameters:                
  87.                 message        specifies which Chooser function to perform    
  88.                 caller        equals 1; specifies the caller is the Chooser
  89.                 objName        name of the selected device
  90.                 zoneName        zone name for AppleTalk devices
  91.                 theList        the list of names
  92.                 p2                parameter used depending upon message value
  93.                 
  94.     returns:
  95.                 OSErr
  96.     
  97. ****************************************************************************************/
  98. pascal OSErr Device(short message, short caller, StringPtr objName, 
  99.                     StringPtr zoneName, ListHandle theList, long p2)
  100. {
  101.     
  102.     OSErr            anErr = noErr;
  103.     extern Str31     gDriverName;
  104.     StringPtr        pDriverName = gDriverName;
  105.     extern gxJob    gJob;                        // Declared in our .a file.
  106.     gxJob            *pJob = &gJob;
  107.  
  108.     if (message == initializeMsg)    // InitializeMsg--start up GX
  109.     {
  110.         FCBPBRec    pb;
  111.  
  112.     /*
  113.         Get the name of our driver for GXHandleChooserMessage.
  114.         (The user may have renamed us.)
  115.     */
  116.         pb.ioCompletion     = nil;
  117.         pb.ioNamePtr         = pDriverName;
  118.         pb.ioVRefNum         = 0;
  119.         pb.ioRefNum         = CurResFile();
  120.         pb.ioFCBIndx         = 0;
  121.         anErr = PBGetFCBInfo(&pb, false);
  122.  
  123.     /*
  124.         Clear *pJob, because it hasn't been initialized yet.  That doesn't
  125.         happen until we pass GXHandleChooserMessage an initializeMsg.
  126.     */
  127.         *pJob = nil;
  128.  
  129.     /*
  130.         We need to initialize GX printing so that we can call
  131.         GXHandleChooserMessage.  Since printing requires a graphics
  132.         client, call GXEnterGraphics first.  If there are errors,
  133.         (for example, due to memory limitations), post an alert.
  134.     */
  135.         if (anErr == noErr)
  136.         {
  137.             GXEnterGraphics();
  138.             anErr = GXGetGraphicsError(nil);
  139.             if (anErr == noErr)
  140.             {
  141.                 anErr = GXInitPrinting();
  142.                 if (anErr != noErr)
  143.                     GXExitGraphics();
  144.             }
  145.                 
  146.             if (anErr != noErr)
  147.                 StopAlert(-4095, nil);
  148.         }
  149.     }
  150.  
  151. /*
  152.     If the Chooser hasn't created a job yet, do nothing unless we were
  153.     sent an initializeMsg.  In its default implementation of
  154.     GXHandleChooserMessage, QuickDraw GX will create the job for our
  155.     driver when it receives an initializeMsg.  It will store a reference
  156.     to it in our pJob pointer.
  157.     
  158.     For all other messages, if a job has been created, call
  159.     GXHandleChooserMessage to handle things.
  160. */
  161.     if (anErr == noErr)
  162.     {
  163.         if ((*pJob != nil) || (message == initializeMsg))
  164.         {
  165.             anErr = GXHandleChooserMessage(pJob, pDriverName, message, caller, objName, zoneName, theList, p2);
  166.     
  167.         /*
  168.             If we just got a terminateMsg, and p2 is also terminateMsg, the
  169.             Chooser is closing.  QuickDraw GX just disposed of the gxJob it
  170.             created earlier when GXHandleChooserMessage was passed
  171.             initializeMsg, so we just need to call GXExitPrinting and
  172.             GXExitGraphics to clean up.
  173.             
  174.             Note that we must test the p2 parameter, because the Chooser
  175.             can also send terminateMsg when it wants to empty the device
  176.             list, but not dispose of us.  For example, this will happen
  177.             when the user turns off AppleTalk in the Chooser.
  178.         */
  179.             if ((message == terminateMsg) && (p2 == terminateMsg))
  180.             {
  181.                 GXExitPrinting();
  182.                 GXExitGraphics();
  183.             }
  184.         }
  185.     }
  186.         
  187.     return(anErr);
  188.     
  189. } // Device
  190.  
  191.  
  192.  
  193. // ------------------------------------------------------------------------
  194. // ENTRY POINT FOR LDEF
  195. // ------------------------------------------------------------------------
  196.  
  197. pascal void LDEF(
  198.     short         message,        // What operation to perform on list
  199.     Boolean     select,            // Is this cell to be selected or not?
  200.     Rect        *theRect,        // Rectangle of this cell, clipped to window
  201.     Cell        theCell,        // Which cell this is
  202.     short        dataOffset,        // Offset into data for this cell
  203.     short        dataLen,        // Length of data for this cell
  204.     ListHandle    theList)        // The list to act upon
  205. /*
  206.     An LDEF that works in two modes:
  207.         - if the first two characters of the cell are valid AppleTalk NBP names (ie, not ≈ ≈)
  208.           then the LDEF is just a basic text LDEF
  209.         - otherwise, it assumes the data is part of a PortListRec, which is
  210.           a structure for icons with text underneath
  211. */
  212.  
  213. {
  214. #pragma unused (theCell, dataLen)
  215.  
  216.     gxPortListRec        theCellContents;
  217.     Rect                iconRect;
  218.     unsigned char        hiliteMode;
  219.     
  220.     switch (message)
  221.         {
  222.         case lDrawMsg:
  223.         case lHiliteMsg:
  224.         
  225.             // save the data to avoid locking things down
  226.             if (dataLen > sizeof(theCellContents) )
  227.                 dataLen = sizeof(theCellContents);
  228.             BlockMove(((*(**theList).cells) + dataOffset), &theCellContents, dataLen );
  229.             
  230.             // draw the cell as an icon, but only if we see our magic marker at the front
  231.             if ( (theCellContents.firstMarker == '≈') && (theCellContents.secondMarker == '≈') )
  232.                 {
  233.                 // center the icon rect on the list with a top margin of 10 pixels
  234.                 iconRect.top = theRect->top + 10;
  235.                 iconRect.left = theRect->left + ((theRect->right - theRect->left) >> 1) - 16;
  236.                 iconRect.bottom = iconRect.top + 32;
  237.                 iconRect.right = iconRect.left + 32;
  238.                 
  239.                 
  240.                 // draw the icon
  241.                 if (theCellContents.iconSuiteHandle != nil)
  242.                     PlotIconSuite(&iconRect,
  243.                             ttNone, (select) ? ttSelected: ttNone,
  244.                             theCellContents.iconSuiteHandle);
  245.                             
  246.                 // Get the general area under the icon in which to draw the label
  247.                 iconRect.left = theRect->left + 2;
  248.                 iconRect.right = iconRect.left + (**theList).cellSize.h - 2;
  249.                 iconRect.top = iconRect.bottom + 2;
  250.                 iconRect.bottom = theRect->bottom;
  251.     
  252.                 // use a nice small font for the label            
  253.                 TextFont(applFont);
  254.                 TextSize(9);
  255.                 
  256.                     {
  257.                     short        labelWidth;
  258.                     short        rectWidth;
  259.                     short        labelHeight;
  260.                     FontInfo    theInfo;
  261.                 
  262.                     // Get rid of any text that was there before
  263.                     EraseRect(&iconRect);
  264.                     iconRect.top += 2;
  265.                     
  266.                     // compute the height of the label                    
  267.                     GetFontInfo(&theInfo);
  268.                     labelHeight = theInfo.ascent + theInfo.leading;
  269.                     
  270.                     // compute where to draw the text
  271.                     iconRect.bottom = iconRect.top + labelHeight;
  272.                     rectWidth = iconRect.right-iconRect.left;
  273.                     
  274.                     // truncate the string to fit within the box
  275.                     TruncString(rectWidth, theCellContents.iconName, smTruncEnd);
  276.                     
  277.                     // compute the new width of the string
  278.                     labelWidth = StringWidth(theCellContents.iconName);
  279.                     
  280.                     // center the string, draw it
  281.                     iconRect.left += (rectWidth >> 1) - (labelWidth >> 1);
  282.                     MoveTo(iconRect.left, iconRect.bottom);
  283.                     DrawString(theCellContents.iconName);
  284.                     
  285.                     if (select)
  286.                         {
  287.                         // compute right and lower edge of box bounding the text we just drew
  288.                         iconRect.right = iconRect.left + labelWidth;
  289.                         iconRect.bottom += theInfo.descent;
  290.                         
  291.                         // outset it, and invert it to select it
  292.                         InsetRect(&iconRect, -1, -1);
  293.                         hiliteMode = LMGetHiliteMode();
  294.                         BitClr(&hiliteMode, pHiliteBit);
  295.                         LMSetHiliteMode(hiliteMode);
  296.                         InvertRect(&iconRect);
  297.                         }
  298.                     }
  299.                     
  300.                 TextFont(applFont);
  301.                 TextSize(0);
  302.                 }
  303.             else
  304.                 {
  305.                 // how boring!  It's only text
  306.                 FontInfo    theInfo;
  307.                 Rect        ourRect;
  308.                 short        cellWidth;
  309.                 
  310.                 // add a margin to the rectangle
  311.                 ourRect = *theRect;
  312.                 ourRect.left += 4;
  313.                 --ourRect.right;
  314.                 cellWidth = ourRect.right - ourRect.left;
  315.                 
  316.                 // erase the rectangle
  317.                 GetFontInfo(&theInfo);
  318.                 EraseRect(theRect);
  319.                 MoveTo(ourRect.left, ourRect.bottom - theInfo.descent);
  320.                 
  321.                 // hey, you can't park that string here -- it's too big!
  322.                 if (TextWidth((Ptr) &theCellContents, 0, dataLen) > cellWidth )
  323.                     {
  324.                     // condense the text first
  325.                     TextFace(condense);
  326.                     
  327.                     // then truncate afterwards
  328.                     TruncText(cellWidth, (Ptr) &theCellContents, &dataLen, smTruncEnd);
  329.                     }
  330.                     
  331.                 // those darn other languages!
  332.                 if (GetSysJust() == teJustRight)
  333.                     Move(cellWidth-TextWidth((Ptr) &theCellContents, 0, dataLen) , 0);
  334.                     
  335.                 OldDrawText((Ptr) &theCellContents, 0, dataLen);
  336.                 
  337.                 // if selected, invert it
  338.                 if (select)
  339.                     {
  340.                     hiliteMode = LMGetHiliteMode();
  341.                     BitClr(&hiliteMode, pHiliteBit);
  342.                     LMSetHiliteMode(hiliteMode);
  343.                     InvertRect(theRect);
  344.                     }
  345.                     
  346.                 // normal text again
  347.                 TextFace(normal);
  348.                 }
  349.                 
  350.             break;
  351.             
  352.         } // switch
  353.         
  354. } // LDEF
  355.